﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Renren.Common;
using Renren.Services;
using System.Windows.Input;
using System.Windows.Data;

namespace Renren.Controls
{
    public class StreamBox : ListBox
    {
        private bool firstLoaded = true;

        private ScrollViewer scrollViewer;
        private LoadingBox headLoadingBox;
        private LoadingBox tailLoadingBox;

        private double startRelativePoint;
        private double actualOffset;

        private DispatcherTimer timer;

        private LoadingCompletedEventArgs headLoadingCompleted;
        private LoadingCompletedEventArgs tailLoadingCompleted;
        
        public event EventHandler<LoadingCompletedEventArgs> LoadHead;
        public event EventHandler<LoadingCompletedEventArgs> LoadTail;

        public static readonly DependencyProperty TailIdleTextProperty =
            DependencyProperty.Register(
            "TailIdleText",
            typeof(string),
            typeof(StreamBox),
            new PropertyMetadata("更新"));

        public static readonly DependencyProperty HeaderTemplateProperty =
            DependencyProperty.Register(
            "HeaderTemplate",
            typeof(DataTemplate),
            typeof(StreamBox),
            new PropertyMetadata(null));

        public string TailIdleText
        {
            get { return (string)GetValue(TailIdleTextProperty); }
            set { SetValue(TailIdleTextProperty, value); }
        }

        public DataTemplate HeaderTemplate
        {
            get { return (DataTemplate)GetValue(HeaderTemplateProperty); }
            set { SetValue(HeaderTemplateProperty, value); }
        }

        public void Refresh()
        {
            this.headLoadingBox.State = LoadingBox.LoadingState.Busy;
            double k = (double)actualOffset / -100;
            k = k > 5 ? 5 : (k < 0.1 ? 0.1 : k);
            this.timer.Interval = new TimeSpan(200 * 1000 * (long)k);
            this.timer.Start();
            LoadHead(this, this.headLoadingCompleted);
        }

        public StreamBox()
        {
            this.DefaultStyleKey = typeof(StreamBox);

            this.headLoadingCompleted = new LoadingCompletedEventArgs(
                () =>
                {
                    this.headLoadingBox.State = LoadingBox.LoadingState.ArrowDown;
                    this.headLoadingBox.Margin = new Thickness(0, -60, 0, 15);
                    this.tailLoadingBox.State = LoadingBox.LoadingState.Idle;
                });

            this.tailLoadingCompleted = new LoadingCompletedEventArgs(
                () =>
                {
                    this.tailLoadingBox.State = LoadingBox.LoadingState.Idle;
                });

            this.timer = new DispatcherTimer();
            this.timer.Tick += (s, e) =>
            {
                this.scrollViewer.ScrollToVerticalOffset(0);
                this.headLoadingBox.Margin = new Thickness(0, 0, 0, 15);
                this.actualOffset = 0;
                this.timer.Stop();
            };

            this.Loaded += (sender, arg) =>
                {
                    if (firstLoaded)
                    {
                        //this.tailLoadingBox.SetBinding(LoadingBox.IdleTextProperty, new Binding { Source = TailIdleText });

                        //this.scrollViewer.ManipulationCompleted += (s, e) =>
                        //{
                        //    if (BaseService.State == ServiceState.Idle)
                        //    {
                        //        if (LoadHead != null && actualOffset <= -100)
                        //        {
                        //            this.Refresh();
                        //        }
                        //        else if (LoadTail != null &&
                        //                 scrollViewer.ScrollableHeight >= 400 &&
                        //                 scrollViewer.ScrollableHeight == scrollViewer.VerticalOffset)
                        //        {
                        //            this.tailLoadingBox.State = LoadingBox.LoadingState.Busy;
                        //            LoadTail(this, this.tailLoadingCompleted);
                        //        }
                        //    }
                        //};

                        //this.scrollViewer.MouseEnter += (s, e) =>
                        //{
                        //    startRelativePoint = e.GetPosition(null).Y;
                        //};

                        //this.scrollViewer.MouseMove += (s, e) =>
                        //{
                        //    actualOffset = scrollViewer.VerticalOffset + startRelativePoint - e.GetPosition(null).Y;
                        //    if (actualOffset <= -100)
                        //    {
                        //        this.headLoadingBox.State = LoadingBox.LoadingState.ArrowUp;
                        //    }
                        //    else
                        //    {
                        //        this.headLoadingBox.State = LoadingBox.LoadingState.ArrowDown;
                        //    }
                        //};

                        //firstLoaded = false;
                    }
                };
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.scrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
            this.headLoadingBox = GetTemplateChild("HeadLoadingBox") as LoadingBox;
            this.tailLoadingBox = GetTemplateChild("TailLoadingBox") as LoadingBox;

            if (this.scrollViewer != null && this.headLoadingBox != null && this.tailLoadingBox != null)
            {
                this.tailLoadingBox.SetBinding(LoadingBox.IdleTextProperty, new Binding { Source = TailIdleText });

                this.scrollViewer.ManipulationCompleted += (s, e) =>
                {
                    if (Service.State == ServiceState.Idle)
                    {
                        if (LoadHead != null && actualOffset <= -100)
                        {
                            this.Refresh();
                        }
                        else if (LoadTail != null &&
                                 scrollViewer.ScrollableHeight >= 400 &&
                                 scrollViewer.ScrollableHeight == scrollViewer.VerticalOffset)
                        {
                            this.tailLoadingBox.State = LoadingBox.LoadingState.Busy;
                            LoadTail(this, this.tailLoadingCompleted);
                        }
                    }
                };

                this.scrollViewer.MouseEnter += (s, e) =>
                {
                    startRelativePoint = e.GetPosition(null).Y;
                };

                this.scrollViewer.MouseMove += (s, e) =>
                {
                    actualOffset = scrollViewer.VerticalOffset + startRelativePoint - e.GetPosition(null).Y;
                    if (actualOffset <= -100)
                    {
                        this.headLoadingBox.State = LoadingBox.LoadingState.ArrowUp;
                    }
                    else
                    {
                        this.headLoadingBox.State = LoadingBox.LoadingState.ArrowDown;
                    }
                }; 
            }
        }
    }
}
